package com.zmn.oms.dubbo.impl.zmn.serviceprovider.order;

import com.alibaba.fastjson.JSON;
import com.zmn.base.engineer.common.dro.foreign.engineer.ForeignEngineerBasicInfoDRO;
import com.zmn.base.engineer.common.dro.foreign.engineer.ForeignEngineerDetailInfoDRO;
import com.zmn.base.engineer.common.enums.EngineerLeaveStatusEnum;
import com.zmn.base.engineer.common.enums.EngineerStopDistributeStatusEnum;
import com.zmn.base.engineer.dubbo.interfaces.foreign.EngineerListRemoteService;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.constant.MasterConsts;
import com.zmn.common.constant.OrderGlobalConsts;
import com.zmn.common.dto.ResponseDTO;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.response.ResponseUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.common.utils.validator.ValidateResult;
import com.zmn.common.utils.validator.ValidatorUtil;
import com.zmn.oms.business.interfaces.remark.OrderRemarkBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.vo.KVDict;
import com.zmn.oms.dubbo.dto.zmn.order.serviceprovider.AccountDIO;
import com.zmn.oms.dubbo.dto.zmn.order.serviceprovider.AccountDRO;
import com.zmn.oms.dubbo.dto.zmn.order.serviceprovider.CheckOutDIO;
import com.zmn.oms.dubbo.dto.zmn.order.serviceprovider.DiscountDIO;
import com.zmn.oms.dubbo.dto.zmn.order.serviceprovider.MasterRetentionDIO;
import com.zmn.oms.dubbo.dto.zmn.order.serviceprovider.OrderDiscountDRO;
import com.zmn.oms.dubbo.dto.zmn.order.serviceprovider.OrderRemarkDIO;
import com.zmn.oms.dubbo.dto.zmn.order.serviceprovider.RefundDIO;
import com.zmn.oms.dubbo.dto.zmn.order.serviceprovider.RefundDRO;
import com.zmn.oms.dubbo.dto.zmn.order.serviceprovider.UpdateOrderDIO;
import com.zmn.oms.dubbo.dto.zmn.order.serviceprovider.remark.OrderRemarkDRO;
import com.zmn.oms.dubbo.impl.zmn.order.OrderBaseRemoteService;
import com.zmn.oms.dubbo.interfaces.zmn.serviceprovider.order.OrderRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.model.dto.order.zmn.UpdateSimpleOrderDTO;
import com.zmn.oms.model.dto.work.modify.amount.ZsDiscountDTO;
import com.zmn.oms.model.dto.work.modify.must.ZsAccountDTO;
import com.zmn.oms.model.dto.work.modify.must.ZsCheckOutDTO;
import com.zmn.oms.model.dto.work.modify.must.ZsMasterRetentionDTO;
import com.zmn.oms.model.dto.work.modify.other.ZsRemarkDTO;
import com.zmn.oms.model.dto.work.refund.RefundDTO;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.remark.OrderRemarkVO;
import com.zmn.oms.model.vo.work.modify.amount.ZsDiscountVO;
import com.zmn.oms.zmn.normal.business.interfaces.discount.ZsNormalOrderDiscountBService;
import com.zmn.oms.zmn.normal.business.interfaces.order.FactoryOrderBService;
import com.zmn.oms.zmn.normal.business.interfaces.refund.RefundBService;
import com.zmn.oms.zmn.normal.business.interfaces.work.financework.ZsNormalFinanceWorkBService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 类描述：服务商  订单操作
 * @author yule
 * @date 2019/05/16 16:05
 */
@Deprecated
@Service(loadbalance = "roundrobin", timeout = 20000, retries = 2, version = DubboConsts.INTERFACE_VERSION, validation = "false")
public class OrderRemoteServiceImpl extends OrderBaseRemoteService implements OrderRemoteService {

    private static final String TAG = "服务商-订单操作";

    private Logger logger = LoggerFactory.getLogger(OrderRemoteServiceImpl.class);

    @Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerListRemoteService engineerListRemoteService;

    @Autowired
    private ZsNormalFinanceWorkBService zsNormalFinanceWorkBService;

    @Autowired
    private FactoryOrderBService factoryOrderBService;

    @Autowired
    private OrderRemarkBService orderRemarkBService;

    @Autowired
    private ZsNormalOrderDiscountBService zsNormalOrderDiscountBService;

    @Autowired
    private RefundBService refundBService;

    @Override
    public ResponseDTO updateOrder(UpdateOrderDIO updateOrderDIO) {
        logger.info("[{}] 修改言而有信订单：{}", TAG, updateOrderDIO);
        ValidateResult validateResult = ValidatorUtil.validator(updateOrderDIO);
        if (!validateResult.isSuccess()) {
            logger.error("[{}] 参数错误：{}", TAG, validateResult.toString());
            return ResponseUtil.responseFail("提交参数错误：" + validateResult.toString());
        }
        try {
            UpdateSimpleOrderDTO spUpdateOrderDTO = BeanMapper.map(updateOrderDIO, UpdateSimpleOrderDTO.class);
            spUpdateOrderDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_SERVICEPROVIDER);// 操作人类型
            spUpdateOrderDTO.setOperator(
                    GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SERVICEPROVIDER) + "-"
                            + updateOrderDIO.getOperator());
            factoryOrderBService.updateSimpleOrder(spUpdateOrderDTO);

            return ResponseUtil.responseSuccess("OK");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("[{}] 订单保存错误：{}", TAG, e);
            return ResponseUtil.responseFail(e.getMessage());
        }
    }

    @Override
    public ResponseDTO saveRemark(OrderRemarkDIO remarkDIO) {
        logger.info("[{}] 保存备注：{}", TAG, remarkDIO);

        // 服务商备注（普通备注）
        if (StringUtil.isNotBlank(remarkDIO.getServiceProviderRemark())) {
            ZsRemarkDTO dto = BeanMapper.map(remarkDIO, ZsRemarkDTO.class);
            dto.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_SERVICEPROVIDER);
            dto.setOperator(
                    GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SERVICEPROVIDER) + "-" + remarkDIO
                            .getOperator());
            zsNormalOrderBService.saveServiceProviderRemark(dto);
        }

        // 工程师备注
        if (StringUtil.isNotBlank(remarkDIO.getMasterRemark())) {
            ZsRemarkDTO dto = BeanMapper.map(remarkDIO, ZsRemarkDTO.class);
            dto.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_SERVICEPROVIDER);
            dto.setOperator(
                    GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SERVICEPROVIDER) + "-" + remarkDIO
                            .getOperator());
            zsNormalOrderBService.saveMasterRemark(dto);
        }

        return ResponseUtil.responseSuccess();
    }

    @Override
    public ResponseDTO saveCheckout(CheckOutDIO checkOutDIO) {
        logger.info("[{}] 保存收单：{}", TAG, checkOutDIO);
        try {
            ZsCheckOutDTO dto = BeanMapper.map(checkOutDIO, ZsCheckOutDTO.class);
            dto.setResultStatus(OrderGlobalConsts.WORK_RESULT_SUCCESS);
            dto.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_SERVICEPROVIDER);
            dto.setPlat(GlobalConsts.PLAT_MARK_YEYX);
            dto.setOperator(
                    GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SERVICEPROVIDER) + "-" + checkOutDIO
                            .getOperator());
            zsNormalFinanceWorkBService.saveFacadeCheckOut(dto);

            return ResponseUtil.responseSuccess();
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.responseFail(e.getMessage());
        }
    }

    @Override
    public ResponseDTO<AccountDRO> account(Long orderId, Long workId) {
        logger.info("[{}] 算账：{}", TAG, "orderId:" + orderId, "workId:" + workId);
        try {
            return ResponseUtil.responseFail("oms不支持算账");
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.responseFail(e.getMessage());
        }
    }

    @Override
    public ResponseDTO<AccountDRO> saveAccount(AccountDIO accountDIO) {
        logger.info("[{}] 保存算账：{}", TAG, accountDIO);
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(accountDIO.getOrderId(), accountDIO.getOrderId());
        Long accountId = orderWork.getAccountId();

        if (accountId != null) {
            return ResponseUtil.responseFail("该订单已完成算账，不可重复算账。");
        }

        try {
            return ResponseUtil.responseFail("oms系统不支持算账");

        } catch (Exception e) {
            logger.error("保存算账异常", e.getMessage(), e);
            return ResponseUtil.responseFail(e.getMessage());
        }
    }

    @Override
    public ResponseDTO<OrderDiscountDRO> discount(Long orderId, Long workId) {
        logger.info("[{}] 加载优惠数据：{}", TAG, orderId);
        try {
            ZsDiscountVO discountVO = zsNormalOrderDiscountBService
                    .findDiscountVO(orderId, workId, OrderConsts.ORDER_OP_TYPE_DISCOUNT_LEVEL_ONE);
            OrderDiscountDRO discountDRO = BeanMapper.map(discountVO, OrderDiscountDRO.class);
            return ResponseUtil.responseSuccess(discountDRO, GlobalConsts.SUCCESS_MSG);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.responseFail(e.getMessage());
        }
    }

    @Override
    public ResponseDTO saveDiscount(DiscountDIO discountDIO) {
        logger.info("[{}] 保存优惠：{}", TAG, discountDIO);
        try {
            ZsDiscountDTO discountDTO = BeanMapper.map(discountDIO, ZsDiscountDTO.class);
            discountDTO.setOperateId(OrderConsts.ORDER_OP_TYPE_DISCOUNT_LEVEL_ONE);//优惠
            discountDTO.setRemoveDiscount(GlobalConsts.NO);
            zsNormalOrderDiscountBService.saveArtificialSp(discountDTO);

            return ResponseUtil.responseSuccess();
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.responseFail(e.getMessage());
        }
    }

    @Override
    public ResponseDTO<RefundDRO> refund(Long orderId, Long workId) {
        logger.info("[{}] 加载退款数据：{}", TAG, orderId);
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);

        RefundDRO refundDRO = BeanMapper.map(orderWork, RefundDRO.class);

        //退款工程师
        refundDRO.setMasterList(
                this.getMasterList(orderWork.getCompanyId(), orderWork.getManageCompanyId(), orderWork.getMasterId()));

        // 退款原因
        OrderRemarkVO orderRemarkVO = orderRemarkBService
                .findOrderRemarkVO(orderId, workId, OrderConsts.ORDER_REMARK_TYPE_REFUND);

        OrderRemarkDRO remarkDRO = BeanMapper.map(orderRemarkVO, OrderRemarkDRO.class);
        refundDRO.setOrderRemarkDRO(remarkDRO);
        refundDRO.setContent(orderRemarkVO != null ? orderRemarkVO.getContent() : null);

        return ResponseUtil.responseSuccess(refundDRO, GlobalConsts.SUCCESS_MSG);
    }

    @Override
    public ResponseDTO saveRefund(RefundDIO refundDIO) {
        logger.info("[{}] 保存退款：{}", TAG, refundDIO);
        try {
            RefundDTO refundDTO = BeanMapper.map(refundDIO, RefundDTO.class);
            refundDTO.setReviewStatus(2);
            refundDTO.setReasonList(refundDIO.getReasonIdList());
            refundBService.commitRefund(refundDTO);

            return ResponseUtil.responseSuccess();
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.responseFail(e.getMessage());
        }
    }

    /**
     * 计算提成金额(服务商结算)
     * @param acountVO
     * @return
     */
    private Integer getCommissionAmount(AccountDRO acountVO) {
        //计算提成金额
        Integer commissionAmount = Optional.ofNullable(acountVO.getServiceProviderRetention()).orElse(0) - Optional
                .ofNullable(acountVO.getInsurance()).orElse(0) - Optional.ofNullable(acountVO.getHelpEach()).orElse(0)
                - Optional.ofNullable(acountVO.getDeposit()).orElse(0) - Optional.ofNullable(acountVO.getVoucherShare())
                .orElse(0) - Optional.ofNullable(acountVO.getDiscountShare()).orElse(0) - Optional
                .ofNullable(acountVO.getIntegralShare()).orElse(0);
        return commissionAmount;
    }

    /**
     * 工程师列表
     * @param companyId
     * @param masterId
     * @return
     */
    private List<KVDict<Integer>> getMasterList(Integer companyId, Integer manageCompanyId, Integer masterId) {
        // 工程师列表，排除 3已离职，6待岗中
        // todo fubiao
        logger.info("getMasterList#listEngineerBySubCompanyIdAndSpCompanyId 入参 {},{}", companyId, manageCompanyId);
        com.zmn.common.dto2.ResponseDTO<List<ForeignEngineerBasicInfoDRO>> responseDTO = engineerListRemoteService.listEngineerBySubCompanyIdAndSpCompanyId(companyId, manageCompanyId);
        logger.info("getMasterList#listEngineerBySubCompanyIdAndSpCompanyId 出参 {}", JSON.toJSONString(responseDTO));
        List<KVDict<Integer>> masterList = Optional.ofNullable(responseDTO.getData()).orElse(Collections.emptyList())
                .stream().filter(item -> !(Objects.equals(item.getOaStatus(), MasterConsts.DEPARTURE) || Objects
                        .equals(item.getOaStatus(), MasterConsts.LEAVE))).map(item -> KVDict.<Integer>builder().value(item.getEngineerId()).text(
                        String.format("%s-%s", item.getRealName(), item.getMobile())).build()).collect(Collectors.toList());

        // 主工程师，未离职或非待岗工程师
        // 状态：1已转正(正常)，2请假中(停止派单) 3已离职， 4试用， 5转正审核中， 6待岗中，  7离职审核中， 8调岗审核中， 9转正审核失败， 10停单中， 11调岗审核失败， 12离职审核失败
        // todo fubiao
        logger.info("getMasterList#getEngineerDetailById 入参 [{}]",masterId);
        com.zmn.common.dto2.ResponseDTO<ForeignEngineerDetailInfoDRO> cacheEngineerByEngineerId = engineerListRemoteService.getEngineerDetailById(masterId);
        logger.info("getMasterList#getEngineerDetailById 出参 [{}]", JSON.toJSONString(cacheEngineerByEngineerId));
        ForeignEngineerDetailInfoDRO baseEngineerDRO = cacheEngineerByEngineerId.getData();
        boolean toStatus = (Objects.equals(baseEngineerDRO.getLeaveStatus(), EngineerLeaveStatusEnum.LEAVE.getCode()) || Objects
                .equals(baseEngineerDRO.getStopDistributeStatus(), EngineerStopDistributeStatusEnum.STOP_DISTRIBUTE.getCode()));
        Integer canRefundMasterId = toStatus ? null : masterId;
        // 设工程师选中状态
        if (canRefundMasterId != null) {
            masterList.forEach(e -> {
                if (Objects.equals(canRefundMasterId, e.getValue())) {
                    e.setSelected(true);
                }
            });
        }

        return masterList;
    }

}
